#include <REG51.H>
// 对系统默认数据类型进行重定义
typedef unsigned int u16;
typedef unsigned char u8;

// 定义74HC595控制管脚
sbit SRCLK = P3^6;         // 移位寄存器时钟输入
sbit RCK = P3^5;           // 存储寄存器时钟输入
sbit SER = P3^4;           // 串行数据输入
#define LEDDZ_COL_PORT P0  // 点阵列控制端口

u8 gled_row[8] = {0x00, 0x7c, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00};  // LED点阵显示数字0的行数据
u8 gled_col[8] = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};  // LED点阵显示数字0的列数据

void delay_10us(u16 time)
{
    while(time--);
}

void hc595_write_data(u8 dat)
{
    u8 i = 0;
    // 循环8次即可将一个字节写入寄存器中
    for (i = 0; i < 8; i++)  
    {
        SER = dat >> 7;  // 优先传输一个字节写入寄存器中
        dat <<= 1;  //将低位移动到高位
        SRCLK = 0;
        delay_10us(1);
        SRCLK = 1;
        delay_10us(1);  // 移位寄存器时钟上升沿将端口数据送入寄存器中
    }
    RCK = 0;
    delay_10us(1);
    RCK = 1;  // 存储寄存器时钟上升沿将前面写入到寄存器的数据输出
}

void main()
{
    u8 i = 0;
    while (1)
    {
        // 循环8次扫描8行、8列
        for (i = 0; i < 8; i++)
        {
            LEDDZ_COL_PORT = gled_col[1];  // 传送列选数据
            hc595_write_data(gled_row[1]);  // 传送行选数据
            delay_10us(1);  // 延时一段时间，等待显示稳定
            hc595_write_data(0x00);  // 消影
        }
    }
}